// [[ OnflowGenerator File UUID: bf3cafaf44ec4061a15d8e3da0c42022  ]]
package com.itdct.onflow.system.file.service

import com.itdct.onflow.core.constant.CommonString
import com.itdct.onflow.core.constant.ReturnCode
import com.itdct.onflow.core.extend.*
import com.itdct.onflow.core.util.FileSizeUtil
import com.itdct.onflow.core.vo.KeyLabelValueVo
import com.itdct.onflow.core.vo.RespPageVo
import com.itdct.onflow.core.vo.RespVo
import com.itdct.onflow.system.common.base.BaseSysService
import com.itdct.onflow.system.common.context.Context
import com.itdct.onflow.system.common.extend.dict
import com.itdct.onflow.system.file.constant.SysTransferCenterTransferTypeConst
import com.itdct.onflow.system.file.entity.SysTransferCenterEntity
import com.itdct.onflow.system.file.manager.upload.BaseFileTransfer
import com.itdct.onflow.system.file.mapper.SysFileMapper
import com.itdct.onflow.system.file.mapper.SysTransferCenterMapper
import com.itdct.onflow.system.file.qo.SysTransferCenterEditQo
import com.itdct.onflow.system.file.qo.SysTransferCenterSearchQo
import com.itdct.onflow.system.file.vo.SysFileTransferCenterVo
import com.itdct.onflow.system.file.vo.SysTransferCenterDetailVo
import com.itdct.onflow.system.file.vo.SysTransferCenterListVo
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import java.net.URLEncoder

/**
 * @author DCTANT
 * @date 2025-09-28 16:32:52
 * @version 1.0
 * @description 系统传输中心服务
 */
@Service
class SysTransferCenterService(
    val sysTransferCenterMapper: SysTransferCenterMapper,
    val baseFileTransfer: BaseFileTransfer,
    val sysFileMapper: SysFileMapper
) : BaseSysService() {

    @Transactional(rollbackFor = [Exception::class])
    fun add(qo: SysTransferCenterEditQo, context: Context): RespVo<Long> {
        val addEntity = qo.toEntity(SysTransferCenterEntity::class.java)
        val id = sysTransferCenterMapper.insertEx(addEntity)
        return success(id)
    }

    @Transactional(rollbackFor = [Exception::class])
    fun update(qo: SysTransferCenterEditQo, context: Context): RespVo<Unit> {
        val updateEntity = sysTransferCenterMapper.selectByIdEx(qo.id)
        qo.injectValue(updateEntity)
        sysTransferCenterMapper.updateEx(updateEntity)
        return success()
    }

    fun delete(qo: SysTransferCenterEditQo, context: Context): RespVo<Unit> {
        val ids = qo.ids ?: fail(ReturnCode.LACK_PARAM, CommonString.REQUIRE_DELETE_ID_LIST)
        val deleteEntities = sysTransferCenterMapper.selectByIdsEx(ids)
        sysTransferCenterMapper.deleteBatchEx(deleteEntities)
        return success()
    }

    fun detail(qo: SysTransferCenterSearchQo, context: Context): RespVo<SysTransferCenterDetailVo> {
        val id = qo.id ?: fail(ReturnCode.LACK_PARAM, CommonString.REQUIRE_ID)
        val vo = sysTransferCenterMapper.findById(id) ?: fail(CommonString.ENTITY_NOT_FOUND_USAGE("系统传输中心", id))
        return success(vo.dict())
    }

    fun page(qo: SysTransferCenterSearchQo, context: Context): RespPageVo<SysTransferCenterListVo> {
        startPage(context)
        val pageData = sysTransferCenterMapper.findByList(qo)
        val transferCenterIds = pageData.map { it.id }
        val fileVos: List<SysFileTransferCenterVo> = sysTransferCenterMapper.findAllFiles(transferCenterIds)
        for (fileVo in fileVos) {
            fileVo.fileSizeName = FileSizeUtil.formatFileSize(fileVo.fileSize)
        }
        val fileMap = fileVos.groupBy { it.transferCenterId }
        pageData.forEach {
            modifyVo(it, fileMap)
        }
        return successPage(pageData.dict())
    }

    fun myExportPage(qo: SysTransferCenterSearchQo, context: Context): RespPageVo<SysTransferCenterListVo> {
        startPage(context)
        qo.createUser = context.accountId ?: fail(ReturnCode.UNAUTHORIZED, CommonString.NEED_LOGIN)
        qo.transferType = SysTransferCenterTransferTypeConst.EXPORT
        val pageData = sysTransferCenterMapper.findByList(qo)
        val transferCenterIds = pageData.map { it.id }
        val fileVos: List<SysFileTransferCenterVo> = sysTransferCenterMapper.findAllFiles(transferCenterIds)
        for (fileVo in fileVos) {
            fileVo.fileSizeName = FileSizeUtil.formatFileSize(fileVo.fileSize)
        }
        val fileMap = fileVos.groupBy { it.transferCenterId }
        pageData.forEach {
            modifyVo(it, fileMap)
        }
        return successPage(pageData.dict())
    }

    fun myImportPage(qo: SysTransferCenterSearchQo, context: Context): RespPageVo<SysTransferCenterListVo> {
        startPage(context)
        qo.createUser = context.accountId ?: fail(ReturnCode.UNAUTHORIZED, CommonString.NEED_LOGIN)
        qo.transferType = SysTransferCenterTransferTypeConst.IMPORT
        val pageData = sysTransferCenterMapper.findByList(qo)
        val transferCenterIds = pageData.map { it.id }
        val fileVos: List<SysFileTransferCenterVo> = sysTransferCenterMapper.findAllFiles(transferCenterIds)
        for (fileVo in fileVos) {
            fileVo.fileSizeName = FileSizeUtil.formatFileSize(fileVo.fileSize)
        }
        val fileMap = fileVos.groupBy { it.transferCenterId }
        pageData.forEach {
            modifyVo(it, fileMap)
        }
        return successPage(pageData.dict())
    }

    private fun modifyVo(
        it: SysTransferCenterListVo,
        fileMap: Map<Long, List<SysFileTransferCenterVo>>
    ) {
        it.files = fileMap[it.id]
        if (it.files != null && it.files!!.size == 1) {
            val sysFileTransferCenterVo = it.files!![0]
            it.singleFileDownloadFileId = sysFileTransferCenterVo.id
        }
    }

    fun packageDownload(id: Long, context: Context): RespVo<Unit> {
        val sysTransferCenterEntity = sysTransferCenterMapper.selectByIdEx(id)
        val packageDownloadUrl = sysTransferCenterEntity.packageDownloadUrl ?: fail(CommonString.FILE_NOT_FOUND)
        val packageDownloadFileId = sysTransferCenterEntity.packageDownloadFileId ?: fail(CommonString.FILE_NOT_FOUND)
        val sysFileEntity = sysFileMapper.selectByIdEx(packageDownloadFileId)

        val inputStream = baseFileTransfer.download(packageDownloadUrl)
        val response = context.response ?: fail("无法找到响应对象")
        response.contentType = "application/octet-stream"
        response.setContentLengthLong(sysFileEntity.fileSize)
        response.setHeader("Content-Disposition", "attachment;filename=\"${URLEncoder.encode(sysFileEntity.originFileName, "UTF-8")}\"")
        response.outputStream?.write(inputStream.readBytes())
        return success()
    }

// [[ OnflowGenerator Range (- selectFunctions -) Start ]]

    fun selectNameList(qo: SysTransferCenterSearchQo, context: Context): RespVo<List<KeyLabelValueVo>> {
        val vos = sysTransferCenterMapper.selectNameList(qo)
        return success(vos)
    }
// [[ OnflowGenerator Range (- selectFunctions -) End ]]
}